package cc.wfu.infrastructure.persistent.repository;

import cc.common.types.entity.ProductActivityEntity;
import cc.common.types.valobj.ProductStateVO;
import cc.wfu.domain.product.model.aggregate.ProductPageAggregate;
import cc.wfu.domain.product.model.entity.ProductDetailEntity;
import cc.wfu.domain.product.model.entity.ProductEntity;
import cc.wfu.domain.product.repository.IProductRepository;
import cc.wfu.infrastructure.persistent.dao.IProductDao;
import cc.wfu.infrastructure.persistent.po.Product;
import cc.wfu.infrastructure.persistent.redis.IRedisService;
import cc.wfu.types.common.RedisKey;
import cc.wfu.types.enums.ProductPriceSort;
import cc.wfu.types.page.PageVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @Author: jia-qiang ljq1024.cc
 * @desc: 商品仓储是实现
 * @Date: 2024-05-25-15:30
 */
@Repository
public class ProductRepository implements IProductRepository {

    @Resource
    protected IProductDao productDao;
    @Resource
    protected ThreadPoolExecutor executor;
    @Resource
    private IRedisService redisService;

    /**
     * 查询商品列表 - 分页，有过滤参数
     * @param productPageAggregate 请求聚合对象
     * @return 商品列表
     */
    @Override
    public PageVO<ProductEntity> queryProducts(ProductPageAggregate productPageAggregate) {
        // 0. 分页使用 mybatis_plus
        LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Product::getState, 1);
        // 1. 过滤参数 - 商品类型
        if (StringUtils.hasLength(productPageAggregate.getProductType())) {
            queryWrapper.eq(Product::getProductType, productPageAggregate.getProductType())
            ;
        }
        // 2. 排序参数
        if (ProductPriceSort.ASC.equals(productPageAggregate.getSort())) {
            queryWrapper.orderByAsc(Product::getProductPrice);
        } else if (ProductPriceSort.DESC.equals(productPageAggregate.getSort())) {
            queryWrapper.orderByDesc(Product::getProductPrice);
        } else {
            queryWrapper.orderByDesc(Product::getSort);
        }
        // 3. 分页参数
        Page<Product> pageReq = new Page<>(productPageAggregate.getPageNum(), productPageAggregate.getPageSize());
        // 4. 分页查询
        Page<Product> pageResponse = productDao.selectPage(pageReq, queryWrapper);
        // 5. 获取数据，进行类型转换
        List<Product> records = pageResponse.getRecords();
        if (records == null || records.isEmpty()) {
            return new PageVO<>(Collections.emptyList(), 0, 0);
        }
        List<ProductEntity> response = new ArrayList<>();
        for (Product product : records) {
            ProductEntity productEntity = ProductEntity.builder()
                    .sku(product.getSku())
                        .productId(product.getProductId())
                        .productTitle(product.getProductTitle())
                        .productSubTitle(product.getProductSubTitle())
                        .productCountSurplus(product.getProductCountSurplus())
                        .productPrice(product.getProductPrice())
                        .productType(product.getProductType())
                        .beginDateTime(product.getBeginDateTime())
                        .endDateTime(product.getEndDateTime())
                    .productName(product.getProductTitle())
                    .state(ProductStateVO.open)
                        .build();

            response.add(productEntity);
        }
        // 5. 预热
        executor.execute(()-> {
            for (ProductEntity productEntity : response) {
                String cacheSkuCountKey = RedisKey.ACTIVITY_SKU_STOCK_COUNT_KEY + productEntity.getSku();
                redisService.setAtomicLong(cacheSkuCountKey, productEntity.getProductCountSurplus());
                String cacheEntityKey = RedisKey.PRODUCT_ACTIVITY_KEY + productEntity.getProductId();
                redisService.setValue(cacheEntityKey,productEntity );
            }
        });
        // 4. 返回数据
        return new PageVO<>(response, pageResponse.getTotal(), pageResponse.getPages());
    }

    /**
     * 查询商品具体信息
     * @param productId 商品ID
     */
    @Override
    public ProductDetailEntity queryProduct(String productId) {
        // 1. 准备查询参数
        Product productReq = Product.builder().state(1).productId(Long.valueOf(productId)).build();
        // 2. 查询
        Product product = productDao.queryProduct(productReq);
        if (product == null) return null;
        // 3. 类型转换并返回
        ProductDetailEntity productDetailEntity = ProductDetailEntity.builder()
                .productId(product.getProductId())
                .productTitle(product.getProductTitle())
                .productSubTitle(product.getProductSubTitle())
                .productCount(product.getProductCount())
                .productCountSurplus(product.getProductCountSurplus())
                .productPrice(product.getProductPrice())
                .productDetail(product.getProductDetail())
                .productMerchant(product.getProductMerchant())
                .beginDateTime(product.getBeginDateTime())
                .endDateTime(product.getEndDateTime())
                .build();
        productDetailEntity.genProductCovers(productReq.getProductCovers());
        return productDetailEntity;
    }

    /**
     * 预热商品 - 查询商品信息
     * @param productId 商品ID
     */
    @Override
    public ProductActivityEntity queryProductEntity(Long productId) {
        // 1. 准备查询参数
        Product productReq = Product.builder().state(1).productId(productId).build();
        // 2. 查询
        Product product = productDao.queryProduct(productReq);
        if (product == null) return null;
        // 3. 类型转换并返回
        return ProductActivityEntity.builder()
                .productId(product.getProductId())
                .productName(product.getProductTitle())
                .state(ProductStateVO.open)
                .beginDateTime(product.getBeginDateTime())
                .endDateTime(product.getEndDateTime())
                .build();
    }
}
